#include "FPCH.h"

#include "FLoaderGDI.h"

#include "FFamily.h"
#include "FLibrary.h"
#include "FMetricsGDI.h"

namespace Font
{
	int CALLBACK GDILoopCallback(
		const LOGFONTW* a_Font,
		const TEXTMETRICW* a_Metrics,
		DWORD a_Type,
		LPARAM a_Param
	)
	{
		LoaderGDI* loader = (LoaderGDI*)a_Param;
		Library* lib = loader->GetLibrary();

		Family* family = lib->CreateFamily(a_Font->lfFaceName);

		Metrics* metrics = new MetricsGDI(lib, loader, family, a_Metrics, a_Font);
		family->AddMetrics(loader, metrics);
		loader->CreateFace(family, metrics);

		return 1;
	}

	int CALLBACK GDISingleCallback(
		const LOGFONTW* a_Font,
		const TEXTMETRICW* a_Metrics,
		DWORD a_Type,
		LPARAM a_Param
	)
	{
		LoaderGDI* loader = (LoaderGDI*)a_Param;
		Library* lib = loader->GetLibrary();

		Family* family = loader->GetCurrentFamily();

		Metrics* metrics = new MetricsGDI(lib, loader, family, a_Metrics, a_Font);
		family->AddMetrics(loader, metrics);
		loader->m_FaceLoaded = loader->CreateFace(family, metrics);

		return 1;
	}

	LoaderGDI::LoaderGDI(Library* a_Library) : Loader(a_Library)
	{
		
	}
	
	LoaderGDI::~LoaderGDI()
	{
		
	}

	bool LoaderGDI::LoadDefault()
	{
		// get installed font families

		LOGFONTW log;
		memset(&log, 0, sizeof(LOGFONTW));
		log.lfCharSet = DEFAULT_CHARSET;
		log.lfFaceName[0] = 0;
		log.lfPitchAndFamily = 0;

		HDC handle = GetDC(0);
		EnumFontFamiliesExW(handle, &log, (FONTENUMPROCW)GDILoopCallback, (LPARAM)m_Library, 0);
		ReleaseDC(0, handle);

		return true;
	}

	Face* LoaderGDI::LoadFace(Family* a_Family, const tb::String& a_Settings)
	{
		m_FamilyCurrent = a_Family;

		LOGFONTW log;
		memset(&log, 0, sizeof(LOGFONTW));
		log.lfCharSet = DEFAULT_CHARSET;
		tb::StringHelper::Copy<wchar_t, char>(
			log.lfFaceName, 
			a_Family->GetName().GetData(), 
			a_Family->GetName().GetLength()
		);
		log.lfPitchAndFamily = 0;

		m_FaceLoaded = NULL;

		HDC handle = GetDC(0);
		int result = EnumFontFamiliesExW(handle, &log, (FONTENUMPROCW)GDISingleCallback, (LPARAM)this, 0);
		ReleaseDC(0, handle);

		return m_FaceLoaded;
	}

	Metrics* LoaderGDI::CreateMetrics(Family* a_Family, unsigned int a_Style, CharMap* a_CharMap)
	{
		return new MetricsGDI(m_Library, this, a_Family, a_Style, a_CharMap);
	}

	Family* LoaderGDI::GetCurrentFamily()
	{
		return m_FamilyCurrent;
	}

}; // namespace Font